#ifndef _TFTP_SERVER_H_
#define _TFTP_SERVER_H_

//#include "net_api.h"
//#include "cube_hal.h"
#include "string.h"
#include <stdint.h>
#include <string.h>
#include "app_ip.h"

typedef char bool;
#define true 1
#define false 0
#define is_true(x) (x)
#define not_true(x) !(x)

#define TFTP_OPCODE_LEN         2
#define TFTP_BLKNUM_LEN         2
#define TFTP_DATA_LEN_MAX       512
#define TFTP_DATA_PKT_HDR_LEN   (TFTP_OPCODE_LEN + TFTP_BLKNUM_LEN)
#define TFTP_ERR_PKT_HDR_LEN    (TFTP_OPCODE_LEN + TFTP_ERRCODE_LEN)
#define TFTP_ACK_PKT_LEN        (TFTP_OPCODE_LEN + TFTP_BLKNUM_LEN)
#define TFTP_DATA_PKT_LEN_MAX   (TFTP_DATA_PKT_HDR_LEN + TFTP_DATA_LEN_MAX)
#define TFTP_MAX_RETRIES        3
#define TFTP_TIMEOUT_INTERVAL   5

/* TFTP error codes as specified in RFC1350  */
typedef enum {
  TFTP_ERR_NOTDEFINED,
  TFTP_ERR_FILE_NOT_FOUND,
  TFTP_ERR_ACCESS_VIOLATION,
  TFTP_ERR_DISKFULL,
  TFTP_ERR_ILLEGALOP,
  TFTP_ERR_UKNOWN_TRANSFER_ID,
  TFTP_ERR_FILE_ALREADY_EXISTS,
  TFTP_ERR_NO_SUCH_USER,
} tftp_errorcode;

/* TFTP opcodes as specified in RFC1350   */
typedef enum {
  TFTP_RRQ = 1,
  TFTP_WRQ = 2,
  TFTP_DATA = 3,
  TFTP_ACK = 4,
  TFTP_ERROR = 5
} tftp_opcode;

typedef struct {
    bool (*open)(char* name, uint8_t opcode);
    uint16_t (*read)(uint8_t blk, uint8_t* buffer);
    void (*write)(uint8_t blk, uint8_t* buffer, uint16_t len);
    void (*close)(void);
} tftp_server_plugin_t;

void tftp_server_input(void);
void tftp_client_output(uint16_t opcode, uint8_t* data, uint16_t len);
#endif // _TFTP_SERVER_H_
